package ch.zbw.sysventory.agent;

import java.net.InetAddress;
import java.net.InterfaceAddress;
import java.net.NetworkInterface;

import ch.zbw.sysventory.agent.utils.PCTypeHelper;

import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.Dispatch;
import com.jacob.com.EnumVariant;
import com.jacob.com.Variant;

public class Agent {

	private String csName;
	private String osName = "os.name";
	private String CSDVersion;

	private String NumberOfLogicalProcessors;
	private String Systemtype;
	private String ram;
	private String ipAddress;
	private short networkPrefix;
	private String DHCPServer;
	private String gateway;
	private String processorName;
	private String numberOfCores;
	private String processorFamily;
	private String sid;
	private String taktrate;
	private String macAddress;
	InetAddress subnet;

	public Agent() {

	}

	public void runAgent() {
		try {

			ActiveXComponent axWMI = new ActiveXComponent(String.format("winmgmts:\\\\%s\\root\\CIMV2", "localhost"));
			// Execute the query
			Variant vCollection = axWMI.invoke("ExecQuery", new Variant("SELECT * FROM Win32_ComputerSystem"));

			EnumVariant enumVariant = new EnumVariant(vCollection.toDispatch());
			Dispatch item = null;
			while (enumVariant.hasMoreElements()) {
				item = enumVariant.nextElement().toDispatch();
				int pcType =  Dispatch.call(item, "PCSystemType").getInt();
				System.out.println("test pc type = " + PCTypeHelper.getPCTypeAsString(pcType));
			}

			/**
			 * BETRIEBSSYSTEM INFO
			 */

			// Name des Betriebssystems
			osName = System.getProperty(osName);

			// Version des Betriebssystems
			CSDVersion = jWMI.getWMIValue("select * from Win32_OperatingSystem", "CSDVersion");

			// Typ des Betriebssystems 32bit oder 64bit
			Systemtype = jWMI.getWMIValue("select * from Win32_ComputerSystem", "Systemtype");

			/**
			 * PROZESSOR INFO
			 */

			// Prozessor Beschreibung mit Taktrate
			processorName = jWMI.getWMIValue("select Name from Win32_Processor", "Name");

			// Prozessor Familie
			processorFamily = jWMI.getWMIValue("select * from Win32_Processor", "Family");

			// Anzahl logische Prozessoren
			NumberOfLogicalProcessors = jWMI.getWMIValue("select * from Win32_Processor", "NumberOfLogicalProcessors");

			// Anzahl Kerne
			numberOfCores = jWMI.getWMIValue("select * from Win32_Processor", "NumberOfCores");

			// Taktrate
			taktrate = jWMI.getWMIValue("select * from Win32_Processor", "MaxClockSpeed");

			/**
			 * COMPUTER INFO
			 */

			// SID
			sid = jWMI.getWMIValue("select * from Win32_UserAccount where Name='Administrator' and LocalAccount=True", "SID");
			sid = sid.substring(0, sid.lastIndexOf("-"));

			// Computername
			csName = jWMI.getWMIValue("select * from Win32_ComputerSystem", "Name");

			// IP Adresse
			InetAddress addr = InetAddress.getLocalHost();
			ipAddress = addr.getHostAddress();

			// MAC Address
			NetworkInterface iface = NetworkInterface.getByInetAddress(addr);
			byte[] mac = iface.getHardwareAddress();
			StringBuilder sb = new StringBuilder(18);
			for (byte b : mac) {
				if (sb.length() > 0)
					sb.append(':');
				sb.append(String.format("%02x", b));
			}
			macAddress = sb.toString();

			// Arbeitsseicher
			ram = jWMI.getWMIValue("select * from Win32_PhysicalMemory", "Capacity");

			String[] ramArray = ram.split("\r\n");
			long totalRam = 0;
			for (int i = 0; i < ramArray.length; i++) {
				System.out.println("ram test=" + ramArray[i]);
				totalRam = totalRam + Long.valueOf(ramArray[i]);
			}

			/**
			 * NETZWERKKARTE INFO
			 */

			// IP Adresse vom DHCP Server
			DHCPServer = jWMI.getWMIValue("select * from Win32_NetworkAdapterConfiguration", "DHCPServer");

			// String[] dhcpArray1 = DHCPServer.split("\r\n");
			// for (int i = 0; i < dhcpArray1.length; i++) {
			// System.out.println(dhcpArray1[i]);
			// }

			// Default Gateway
			// Subnet IP
			for (InterfaceAddress address : iface.getInterfaceAddresses()) {

				networkPrefix = address.getNetworkPrefixLength();
			}

			try {
				int shiftby = (1 << 31);

				for (int i = networkPrefix - 1; i > 0; i--) {
					shiftby = (shiftby >> 1);
				}
				String maskString = Integer.toString((shiftby >> 24) & 255) + "." + Integer.toString((shiftby >> 16) & 255) + "." + Integer.toString((shiftby >> 8) & 255) + "."
						+ Integer.toString(shiftby & 255);

				subnet = InetAddress.getByName(maskString);
			} catch (Exception e) {
				e.printStackTrace();
			}

			/**
			 * Ausgabe
			 */

			System.out.println("Ausgabe Agent :");
			System.out.println();
			System.out.println("SID: " + sid);
			System.out.println("Betriebssystem: " + osName + " " + CSDVersion + " " + Systemtype);
			System.out.println("Computer Name: " + csName);

			System.out.println("RAM total: " + totalRam);
			System.out.println("Logische Threads Prozessoren: " + NumberOfLogicalProcessors);
			System.out.println("Anzahl Kerne: " + numberOfCores);
			System.out.println("Prozessor Familie: " + processorFamily);
			System.out.println("Prozessor Name: " + processorName);
			System.out.println("Taktrate: " + taktrate);
			System.out.println("MAC Adresse: " + macAddress);
			System.out.println("IP Adresse: " + ipAddress);
			System.out.println("IP Subnet: " + networkPrefix + subnet);
			System.out.println("DHCP Server: " + DHCPServer);
			System.out.println("Gateway: " + gateway);

		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}
}
